package com.nervenets.web.redis;

import com.google.gson.Gson;
import com.nervenets.utils.StringUtils;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCommands;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Joe on 2017/12/16.
 */
@Component
public class RedisSetDao {
    @Resource
    JedisCommands jedisCluster;

    private static boolean assertNull(String string) {
        return StringUtils.isEmpty(string)
                || "NIL".equals(string.toUpperCase())
                || "NULL".equals(string.toUpperCase());
    }

    private static String toJson(RedisDomain domain) {
        return new Gson().toJson(domain);
    }

    public void saveOrUpdate(RedisSetDomain domain) {
        jedisCluster.hset(domain.getRedisKey(), domain.getField(), toJson(domain));
        if (domain.getExpire() > 0) {
            jedisCluster.expire(domain.getRedisKey(), domain.getExpire());
        }
    }

    public void saveOrUpdate(RedisSetDomain... domain) {
        for (RedisSetDomain redisSetDomain : domain) {
            saveOrUpdate(redisSetDomain);
        }
    }

    public boolean exists(RedisSetDomain domain) {
        return jedisCluster.hexists(domain.getRedisKey(), domain.getField());
    }

    public <T extends RedisSetDomain> T getRedisSetDomain(T domain) {
        String tJson = jedisCluster.hget(domain.getRedisKey(), domain.getField());
        if (assertNull(tJson)) {
            return null;
        }
        return (T) new Gson().fromJson(tJson, domain.getClass());
    }

    public <T extends RedisSetDomain> List<T> getAllRedisSetDomain(T domain) {
        List<T> rtnValue = new ArrayList<T>();
        Gson gson = new Gson();
        Map<String, String> setAll = jedisCluster.hgetAll(domain.getRedisKey());
        if (null != setAll && !setAll.isEmpty()) {
            for (String key : setAll.keySet()) {
                String tJson = setAll.get(key);
                T filed = (T) gson.fromJson(tJson, domain.getClass());
                rtnValue.add(filed);
            }
        }
        return rtnValue;
    }

    public <T extends RedisSetDomain> void delete(T domain) {
        jedisCluster.hdel(domain.getRedisKey(), domain.getField());
    }

    public JedisCommands getCluster() {
        return jedisCluster;
    }

    public void incrBy(RedisOrderedSetDomain domain, int offset) {
        jedisCluster.hincrBy(domain.getRedisKey(), domain.getField(), offset);
    }

    public void incr(RedisOrderedSetDomain domain) {
        jedisCluster.hincrBy(domain.getRedisKey(), domain.getField(), 1);
    }
}
